require 'thor'
require 'yaml'
require 'fileutils'
require 'proxy_pump/generator'
module ProxyPump
  class CLI < ::Thor

    CONFIG_YAML_FILE  = 'config.yml'.freeze

    desc 'new', 'Create a workspace with specified name'
    def new(name = 'proxy_pump')
      ProxyPump::Generator.start [name]
      puts 'Configuarion can be modified in config.yml'
    end

    desc 'proxies', 'Show available proxies'
    option :output, aliases: 'O', desc: 'export to the specified json format file'
    def proxies
      with_config do
        begin
          proxies = ProxyPump.cache.all.sort { |a, b| a[:elapsed] <=> b[:elapsed] }
          pretty_json = JSON.pretty_generate(count: proxies.count, proxies: proxies)
          if output = options[:output]
            extname = File.extname(output).downcase
            output  = output[0...output.length - extname.length] << '.json'
            File.open(output, 'w') { |f| f.puts pretty_json }
          else
            puts pretty_json
          end
        ensure
          ProxyPump.cache.close
        end
      end
    end

    desc 'server', 'Start server'
    option :host, aliases: 'h', default: 'localhost', desc: 'Bind server to the specified IP.'
    option :port, aliases: 'P', type: :numeric, default: 9292, desc: 'Run server on the specified port.'
    option :daemonize, aliases: 'd', type: :boolean, default: false, desc: 'Runs server as a Daemon'
    option :pidfile, aliases: 'p', default: 'tmp/pids/server.pid', desc: 'File to write PID'
    option :logfile, aliases: 'l', desc: 'File to output server logs'
    def server
      with_config do
        ProxyPump.configure do |conf|
          conf.server ||= {}
          conf.server[:host]      = options[:host]
          conf.server[:port]      = options[:port]
          conf.server[:daemonize] = options[:daemonize]
          conf.server[:pidfile]   = options[:pidfile]
          conf.server[:logfile]   = options[:logfile] || conf.server[:logfile]
        end
        ProxyPump.server.start
      end
    end

    desc 'pump', 'Start pump'
    option :daemonize, aliases: 'd', type: :boolean, default: false, desc: 'Runs pump as a Daemon'
    option :pidfile, aliases: 'p', default: 'tmp/pids/pump.pid', desc: 'File to write PID'
    option :logfile, aliases: 'l', desc: 'File to output pump logs'
    def pump
      with_config do
        ProxyPump.configure do |conf|
          conf.pump ||= {}
          conf.pump[:daemonize] = options[:daemonize]
          conf.pump[:pidfile]   = options[:pidfile]
          conf.pump[:logfile]   = options[:logfile] || conf.pump[:logfile]
        end
        ProxyPump.pump.start
      end
    end

    desc 'stop', 'Stop server'
    def stop
      begin
        with_config do
          server_pid = ProxyPump.configuration.server[:pidfile]
          Process.kill(:INT, File.read(server_pid).to_i) if File.exists?(server_pid)
          pump_pid   = ProxyPump.configuration.pump[:pidfile]
          Process.kill(:INT, File.read(pump_pid).to_i) if File.exists?(pump_pid)
        end
      rescue => e
        puts "Oops! #{e.message} (#{e.class})"
      end
    end

    private

      def with_config(&block)
        ProxyPump.load(CONFIG_YAML_FILE)
        yield
      end

  end # CLI
end # PxPump
